package com.example.beangenerate.util;

import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

@Service
public class ModelChange {

    /**
     * 映射结果集到JavaBean
     *
     * @param resultSet
     * @param clazz
     * @return
     * @throws Exception
     */
    public static Object getBeans(ResultSet resultSet, Class clazz) throws Exception {
        //获取要封装的javabean声明的属性
        Field[] fields = clazz.getDeclaredFields();
        //获取ResultSetMetaData(包含ResultSet中列的名称和类型的信息)
        ResultSetMetaData metaData = resultSet.getMetaData();
        //光标移到最后
        resultSet.last();
        //获取结果数据条数
        int rows = resultSet.getRow();
        //光标移到第一条数据前
        resultSet.beforeFirst();
        //获取查询结果列数
        int columnCount = metaData.getColumnCount();
        if (rows > 1) {
            List<Object> list = new ArrayList<>();
            //遍历ResultSet
            while (resultSet.next()) {
                //调用无参构造实例化对象
                Object object = clazz.newInstance();
                for (int j = 1; j <= columnCount; j++) {
                    //获取列名
                    String columnName = metaData.getColumnName(j);
                    //匹配JavaBean的属性,然后赋值
                    for (Field field : fields) {
                        field.setAccessible(true);
                        if (field.getName().equalsIgnoreCase(camelName(columnName))) {
                            field.set(object, resultSet.getObject(columnName));
                        }
                    }
                }
                list.add(object);
            }
            return list;
        } else {
            Object object = clazz.newInstance();
            //遍历ResultSet
            while (resultSet.next()) {
                for (int j = 1; j <= columnCount; j++) {
                    String columnName = metaData.getColumnName(j);
                    for (Field field : fields) {
                        field.setAccessible(true);
                        if (field.getName().equalsIgnoreCase(columnName)) {
                            field.set(object, resultSet.getObject(columnName));
                        }
                    }
                }
            }
            return object;
        }
    }

    /**
     * 将驼峰式命名的字符串转换为下划线大写方式。如果转换前的驼峰式命名的字符串为空，则返回空字符串。</br>
     * 例如：HelloWorld->HELLO_WORLD
     * @param name 转换前的驼峰式命名的字符串
     * @return 转换后下划线大写方式命名的字符串
     */
    public static String underscoreName(String name) {
        StringBuilder result = new StringBuilder();
        if (name != null && name.length() > 0) {
            // 将第一个字符处理成大写
            result.append(name.substring(0, 1).toUpperCase());
            // 循环处理其余字符
            for (int i = 1; i < name.length(); i++) {
                String s = name.substring(i, i + 1);
                // 在大写字母前添加下划线
                if (s.equals(s.toUpperCase()) && !Character.isDigit(s.charAt(0))) {
                    result.append("_");
                }
                // 其他字符直接转成大写
                result.append(s.toUpperCase());
            }
        }
        return result.toString();
    }

    /**
     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空，则返回空字符串。</br>
     * 例如：HELLO_WORLD->HelloWorld
     * @param name 转换前的下划线大写方式命名的字符串
     * @return 转换后的驼峰式命名的字符串
     */
    public static String camelName(String name) {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || name.isEmpty()) {
            // 没必要转换
            return "";
        } else if (!name.contains("_")) {
            // 不含下划线，仅将首字母小写
            return name.substring(0, 1).toLowerCase() + name.substring(1);
        }
        // 用下划线将原始字符串分割
        String camels[] = name.split("_");
        for (String camel :  camels) {
            // 跳过原始字符串中开头、结尾的下换线或双重下划线
            if (camel.isEmpty()) {
                continue;
            }
            // 处理真正的驼峰片段
            if (result.length() == 0) {
                // 第一个驼峰片段，全部字母都小写
                result.append(camel.toLowerCase());
            } else {
                // 其他的驼峰片段，首字母大写
                result.append(camel.substring(0, 1).toUpperCase());
                result.append(camel.substring(1).toLowerCase());
            }
        }
        return result.toString();
    }

    /**
     * 驼峰处理   USER_ID-->userId
     * @param name 转换前的下划线大写方式命名的字符串
     * @param flag 转换前的下划线大写方式命名的字符串
     * @return 转换后的驼峰式命名的字符串
     */
    //驼峰处理   USER_ID-->userId  flag :首字母是否大写 true:大写
    public String changeModel(String name,boolean flag){
        String resultName = "";
        name = name.toLowerCase();
        String[] nameList = name.split("_");
        for(int i = 0;i<nameList.length;i++){
            if(i!=0&&nameList[i].length()>1){
                nameList[i] = nameList[i].substring(0,1).toUpperCase().concat(nameList[i].substring(1));
            }
            resultName = resultName+nameList[i];
        }
        if(flag){
            resultName = resultName.substring(0,1).toUpperCase().concat(resultName.substring(1));
        }
        return resultName;
    }
}


